package com.fatri.lessionsimple.opengl.drawer

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.opengl.GLES20
import android.opengl.GLUtils
import android.opengl.Matrix
import com.fatri.lessionsimple.R
import com.fatri.lessionsimple.opengl.IDrawer
import com.fatri.lessionsimple.opengl.OpenGLTools
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer

class PicDrawer(ctx: Context) : IDrawer(ctx) {
    lateinit var bmp: Bitmap

    private val COORD_PER_VERTEX = 2


//    private var vertex = floatArrayOf(
//        -0.5f, 0.5f, 0f,
//        -0.5f, -0.5f, 0f,
//        0.5f, -0.5f, 0f
//    )


    private var mProgram = 0

    var sPos = floatArrayOf(
        -1f, 1f,  //左上
        -1f, -1f,         //左下
        1f, 1f,         //右上
        1f, -1f        //右下

    )


    val sCoord = floatArrayOf(
        0f, 0f,
        0f, 1f,
        1f, 0f,
        1f, 1f
    )

    init {
        bmp = BitmapFactory.decodeResource(ctx.resources, R.drawable.fengj)
    }

    private var vTextureHandler=-1
    private var mPositionHandle = 0
    private var mFragHandler = 0
    private lateinit var vertexBuffer: FloatBuffer
    private lateinit var fragBuffer: FloatBuffer
    override fun onSurfaceCreated() {
//        GLES20.glClear(0)

        val bb = ByteBuffer.allocateDirect(sPos.size * 4)
        bb.order(ByteOrder.nativeOrder())
        vertexBuffer = bb.asFloatBuffer()
        vertexBuffer.put(sPos)
        vertexBuffer.position(0)

        val cc = ByteBuffer.allocateDirect(sCoord.size * 4)
        cc.order(ByteOrder.nativeOrder())
        fragBuffer = cc.asFloatBuffer()
        fragBuffer.put(sCoord)
        fragBuffer.position(0)


        val vertextShader = loadShader(
            GLES20.GL_VERTEX_SHADER,
            OpenGLTools.readShaderCode(ctx, "bmp/bmp_vertex.glsl")
        )
        val fragShader = loadShader(
            GLES20.GL_FRAGMENT_SHADER,
            OpenGLTools.readShaderCode(ctx, "bmp/bmp_texture.glsl")
        )


        mProgram = GLES20.glCreateProgram()
        GLES20.glAttachShader(mProgram, vertextShader)
        GLES20.glAttachShader(mProgram, fragShader)
        GLES20.glLinkProgram(mProgram)


    }

    private val mViewMatrix = FloatArray(16)
    private val mProjectMatrix = FloatArray(16)
    private val mMVPMatrix = FloatArray(16)
    override fun onSurfaceChanged(width: Int, height: Int) {
        val bmpWidth: Int = bmp.getWidth()
        val bmpHeight: Int = bmp.getHeight()
        val bmpRatio = bmpWidth / bmpHeight.toFloat()
        val ratio = width / height.toFloat()
        if (width > height) {
            if (bmpRatio > ratio) {
                Matrix.orthoM(
                    mProjectMatrix,
                    0,
                    -ratio * bmpRatio,
                    ratio * bmpRatio,
                    -1f,
                    1f,
                    3f,
                    7f
                )
            } else {
                Matrix.orthoM(
                    mProjectMatrix,
                    0,
                    -ratio / bmpRatio,
                    ratio / bmpRatio,
                    -1f,
                    1f,
                    3f,
                    7f
                )
            }
        } else {
            if (bmpRatio > ratio) {
                Matrix.orthoM(
                    mProjectMatrix,
                    0,
                    -1f,
                    1f,
                    -1 / ratio * bmpRatio,
                    1 / ratio * bmpRatio,
                    3f,
                    7f
                )
            } else {
                Matrix.orthoM(
                    mProjectMatrix,
                    0,
                    -1f,
                    1f,
                    -bmpRatio / ratio,
                    bmpRatio / ratio,
                    3f,
                    7f
                )
            }
        }
        //设置相机位置
        //设置相机位置
        Matrix.setLookAtM(mViewMatrix, 0, 0f, 0f, 7.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
        //计算变换矩阵
        //计算变换矩阵
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectMatrix, 0, mViewMatrix, 0)
    }

    override fun onDrawFrame() {
        GLES20.glUseProgram(mProgram)


        GLES20.glGetUniformLocation(mProgram,"vTexture")
        GLES20.glUniform1i(vTextureHandler,0)
        val textureId = createTexture()

        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition")
        GLES20.glEnableVertexAttribArray(mPositionHandle)
        GLES20.glVertexAttribPointer(
            mPositionHandle,
            COORD_PER_VERTEX,
            GLES20.GL_FLOAT,
            false,
            COORD_PER_VERTEX * 4,
            vertexBuffer
        )

        mFragHandler = GLES20.glGetAttribLocation(mProgram, "vCoordinate")
        GLES20.glEnableVertexAttribArray(mFragHandler)
        GLES20.glVertexAttribPointer(mFragHandler, 2, GLES20.GL_FLOAT, false, 0, fragBuffer)

//        //给vMatrix赋值
        val matrixHandler = GLES20.glGetUniformLocation(mProgram, "vMatrix")
        GLES20.glUniformMatrix4fv(matrixHandler, 1, false, mMVPMatrix, 0)

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, sPos.size / COORD_PER_VERTEX)


        GLES20.glDisableVertexAttribArray(mPositionHandle)

    }

    override fun release() {
    }


    private fun createTexture(): Int {
        val texture = IntArray(1)
        if (!bmp.isRecycled) {
            //生成纹理
            GLES20.glGenTextures(1, texture, 0)

            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0])

            //设置缩小过滤为使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色
            GLES20.glTexParameterf(
                GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_NEAREST.toFloat()
            )

            //设置放大过滤为使用纹理中坐标最接近的若干个颜色，通过加权平均算法得到需要绘制的像素颜色
            GLES20.glTexParameterf(
                GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR.toFloat()
            )
            //设置环绕方向S，截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合
            GLES20.glTexParameterf(
                GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_WRAP_S,
                GLES20.GL_CLAMP_TO_EDGE.toFloat()
            )
            //设置环绕方向T，截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合
            GLES20.glTexParameterf(
                GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_WRAP_T,
                GLES20.GL_CLAMP_TO_EDGE.toFloat()
            )

            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0)
            return texture[0]

        }
        return 0
    }
}